<!DOCTYPE html>
<html>
<head>
<title>编码设计规范</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">
/* GitHub stylesheet for MarkdownPad (http://markdownpad.com) */
/* Author: Nicolas Hery - http://nicolashery.com */
/* Version: b13fe65ca28d2e568c6ed5d7f06581183df8f2ff */
/* Source: https://github.com/nicolahery/markdownpad-github */

/* RESET
=============================================================================*/

html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video {
  margin: 0;
  padding: 0;
  border: 0;
}

/* BODY
=============================================================================*/

body {
  font-family: Helvetica, arial, freesans, clean, sans-serif;
  font-size: 14px;
  line-height: 1.6;
  color: #333;
  background-color: #fff;
  padding: 20px;
  max-width: 960px;
  margin: 0 auto;
}

body>*:first-child {
  margin-top: 0 !important;
}

body>*:last-child {
  margin-bottom: 0 !important;
}

/* BLOCKS
=============================================================================*/

p, blockquote, ul, ol, dl, table, pre {
  margin: 15px 0;
}

/* HEADERS
=============================================================================*/

h1, h2, h3, h4, h5, h6 {
  margin: 20px 0 10px;
  padding: 0;
  font-weight: bold;
  -webkit-font-smoothing: antialiased;
}

h1 tt, h1 code, h2 tt, h2 code, h3 tt, h3 code, h4 tt, h4 code, h5 tt, h5 code, h6 tt, h6 code {
  font-size: inherit;
}

h1 {
  font-size: 28px;
  color: #000;
}

h2 {
  font-size: 24px;
  border-bottom: 1px solid #ccc;
  color: #000;
}

h3 {
  font-size: 18px;
}

h4 {
  font-size: 16px;
}

h5 {
  font-size: 14px;
}

h6 {
  color: #777;
  font-size: 14px;
}

body>h2:first-child, body>h1:first-child, body>h1:first-child+h2, body>h3:first-child, body>h4:first-child, body>h5:first-child, body>h6:first-child {
  margin-top: 0;
  padding-top: 0;
}

a:first-child h1, a:first-child h2, a:first-child h3, a:first-child h4, a:first-child h5, a:first-child h6 {
  margin-top: 0;
  padding-top: 0;
}

h1+p, h2+p, h3+p, h4+p, h5+p, h6+p {
  margin-top: 10px;
}

/* LINKS
=============================================================================*/

a {
  color: #4183C4;
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
}

/* LISTS
=============================================================================*/

ul, ol {
  padding-left: 30px;
}

ul li > :first-child, 
ol li > :first-child, 
ul li ul:first-of-type, 
ol li ol:first-of-type, 
ul li ol:first-of-type, 
ol li ul:first-of-type {
  margin-top: 0px;
}

ul ul, ul ol, ol ol, ol ul {
  margin-bottom: 0;
}

dl {
  padding: 0;
}

dl dt {
  font-size: 14px;
  font-weight: bold;
  font-style: italic;
  padding: 0;
  margin: 15px 0 5px;
}

dl dt:first-child {
  padding: 0;
}

dl dt>:first-child {
  margin-top: 0px;
}

dl dt>:last-child {
  margin-bottom: 0px;
}

dl dd {
  margin: 0 0 15px;
  padding: 0 15px;
}

dl dd>:first-child {
  margin-top: 0px;
}

dl dd>:last-child {
  margin-bottom: 0px;
}

/* CODE
=============================================================================*/

pre, code, tt {
  font-size: 12px;
  font-family: Consolas, "Liberation Mono", Courier, monospace;
}

code, tt {
  margin: 0 0px;
  padding: 0px 0px;
  white-space: nowrap;
  border: 1px solid #eaeaea;
  background-color: #f8f8f8;
  border-radius: 3px;
}

pre>code {
  margin: 0;
  padding: 0;
  white-space: pre;
  border: none;
  background: transparent;
}

pre {
  background-color: #f8f8f8;
  border: 1px solid #ccc;
  font-size: 13px;
  line-height: 19px;
  overflow: auto;
  padding: 6px 10px;
  border-radius: 3px;
}

pre code, pre tt {
  background-color: transparent;
  border: none;
}

kbd {
    -moz-border-bottom-colors: none;
    -moz-border-left-colors: none;
    -moz-border-right-colors: none;
    -moz-border-top-colors: none;
    background-color: #DDDDDD;
    background-image: linear-gradient(#F1F1F1, #DDDDDD);
    background-repeat: repeat-x;
    border-color: #DDDDDD #CCCCCC #CCCCCC #DDDDDD;
    border-image: none;
    border-radius: 2px 2px 2px 2px;
    border-style: solid;
    border-width: 1px;
    font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
    line-height: 10px;
    padding: 1px 4px;
}

/* QUOTES
=============================================================================*/

blockquote {
  border-left: 4px solid #DDD;
  padding: 0 15px;
  color: #777;
}

blockquote>:first-child {
  margin-top: 0px;
}

blockquote>:last-child {
  margin-bottom: 0px;
}

/* HORIZONTAL RULES
=============================================================================*/

hr {
  clear: both;
  margin: 15px 0;
  height: 0px;
  overflow: hidden;
  border: none;
  background: transparent;
  border-bottom: 4px solid #ddd;
  padding: 0;
}

/* TABLES
=============================================================================*/

table th {
  font-weight: bold;
}

table th, table td {
  border: 1px solid #ccc;
  padding: 6px 13px;
}

table tr {
  border-top: 1px solid #ccc;
  background-color: #fff;
}

table tr:nth-child(2n) {
  background-color: #f8f8f8;
}

/* IMAGES
=============================================================================*/

img {
  max-width: 100%
}
</style>
<style type="text/css">
.highlight  { background: #ffffff; }
.highlight .c { color: #999988; font-style: italic } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { font-weight: bold } /* Keyword */
.highlight .o { font-weight: bold } /* Operator */
.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */
.highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */
.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */
.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #999999 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #aaaaaa } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { font-weight: bold } /* Keyword.Constant */
.highlight .kd { font-weight: bold } /* Keyword.Declaration */
.highlight .kp { font-weight: bold } /* Keyword.Pseudo */
.highlight .kr { font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #009999 } /* Literal.Number */
.highlight .s { color: #d14 } /* Literal.String */
.highlight .na { color: #008080 } /* Name.Attribute */
.highlight .nb { color: #0086B3 } /* Name.Builtin */
.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */
.highlight .no { color: #008080 } /* Name.Constant */
.highlight .ni { color: #800080 } /* Name.Entity */
.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */
.highlight .nn { color: #555555 } /* Name.Namespace */
.highlight .nt { color: #000080 } /* Name.Tag */
.highlight .nv { color: #008080 } /* Name.Variable */
.highlight .ow { font-weight: bold } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mf { color: #009999 } /* Literal.Number.Float */
.highlight .mh { color: #009999 } /* Literal.Number.Hex */
.highlight .mi { color: #009999 } /* Literal.Number.Integer */
.highlight .mo { color: #009999 } /* Literal.Number.Oct */
.highlight .sb { color: #d14 } /* Literal.String.Backtick */
.highlight .sc { color: #d14 } /* Literal.String.Char */
.highlight .sd { color: #d14 } /* Literal.String.Doc */
.highlight .s2 { color: #d14 } /* Literal.String.Double */
.highlight .se { color: #d14 } /* Literal.String.Escape */
.highlight .sh { color: #d14 } /* Literal.String.Heredoc */
.highlight .si { color: #d14 } /* Literal.String.Interpol */
.highlight .sx { color: #d14 } /* Literal.String.Other */
.highlight .sr { color: #009926 } /* Literal.String.Regex */
.highlight .s1 { color: #d14 } /* Literal.String.Single */
.highlight .ss { color: #990073 } /* Literal.String.Symbol */
.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */
.highlight .vc { color: #008080 } /* Name.Variable.Class */
.highlight .vg { color: #008080 } /* Name.Variable.Global */
.highlight .vi { color: #008080 } /* Name.Variable.Instance */
.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */
.pl-c {
    color: #969896;
}

.pl-c1,.pl-mdh,.pl-mm,.pl-mp,.pl-mr,.pl-s1 .pl-v,.pl-s3,.pl-sc,.pl-sv {
    color: #0086b3;
}

.pl-e,.pl-en {
    color: #795da3;
}

.pl-s1 .pl-s2,.pl-smi,.pl-smp,.pl-stj,.pl-vo,.pl-vpf {
    color: #333;
}

.pl-ent {
    color: #63a35c;
}

.pl-k,.pl-s,.pl-st {
    color: #a71d5d;
}

.pl-pds,.pl-s1,.pl-s1 .pl-pse .pl-s2,.pl-sr,.pl-sr .pl-cce,.pl-sr .pl-sra,.pl-sr .pl-sre,.pl-src,.pl-v {
    color: #df5000;
}

.pl-id {
    color: #b52a1d;
}

.pl-ii {
    background-color: #b52a1d;
    color: #f8f8f8;
}

.pl-sr .pl-cce {
    color: #63a35c;
    font-weight: bold;
}

.pl-ml {
    color: #693a17;
}

.pl-mh,.pl-mh .pl-en,.pl-ms {
    color: #1d3e81;
    font-weight: bold;
}

.pl-mq {
    color: #008080;
}

.pl-mi {
    color: #333;
    font-style: italic;
}

.pl-mb {
    color: #333;
    font-weight: bold;
}

.pl-md,.pl-mdhf {
    background-color: #ffecec;
    color: #bd2c00;
}

.pl-mdht,.pl-mi1 {
    background-color: #eaffea;
    color: #55a532;
}

.pl-mdr {
    color: #795da3;
    font-weight: bold;
}

.pl-mo {
    color: #1d3e81;
}
.task-list {
padding-left:10px;
margin-bottom:0;
}

.task-list li {
    margin-left: 20px;
}

.task-list-item {
list-style-type:none;
padding-left:10px;
}

.task-list-item label {
font-weight:400;
}

.task-list-item.enabled label {
cursor:pointer;
}

.task-list-item+.task-list-item {
margin-top:3px;
}

.task-list-item-checkbox {
display:inline-block;
margin-left:-20px;
margin-right:3px;
vertical-align:1px;
}
</style>
<link rel="stylesheet" href="https://cdn.bootcss.com/highlight.js/8.0/styles/solarized_dark.min.css">
<script src="https://cdn.bootcss.com/highlight.js/8.0/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
<!-- -->
<script type="text/javascript">
    function wrapOldContentByDiv() {
        var oldContentDiv = document.createElement("div");
        oldContentDiv.style.cssText = "float:right; width:72%; padding-left: 3%; padding-right:3%;border-left: 1px solid #CACACA;";
        oldContentDiv.innerHTML = document.body.innerHTML;
        document.body.style["max-width"] = "100%";
        document.body.style["margin"] = "20px";
        document.body.style["padding"] = "0";
        document.body.innerHTML = '';
        document.body.appendChild(oldContentDiv);
    };

    function addDirectorySwitch(directoryDiv) {
        var directorySwitchP = document.createElement("p");
        directorySwitchP.style.cssText = "text-align: left; margin: 0;";
        directoryDiv.appendChild(directorySwitchP);

        var ele_span = document.createElement("span");
        ele_span.style.cssText = "font-weight: 1000;";
        var ele_text = document.createTextNode("目录");
        ele_span.appendChild(ele_text);

        var ele_a = document.createElement("a");
        ele_a.appendChild(document.createTextNode("[-]"));
        ele_a.setAttribute("href", "#");
        ele_a.setAttribute("onclick", "javascript:return switchAllDirectory(this);");
        ele_a.setAttribute("title", "Click to Open TOC");

        ele_span.appendChild(ele_a);
        directorySwitchP.appendChild(ele_span);
    }

    function createTree(parentNode, tags, index, maxLevel) {
        if (index >= tags.length) {
            return -1;
        }

        var lastLevel = -1;
        for (var i = index; i < tags.length; i++) {
            var header = tags[i];
            var level = parseInt(header.tagName.substr(1), 10);

            var childNode = {'tag': header, 'childNodes': [], 'level': level};
            if (level > parentNode.level) {
                if (lastLevel > 0 && level > lastLevel) {
                    // 子子类
                    index = createTree(parentNode.childNodes[parentNode.childNodes.length - 1], tags, i);
                    if (index < 0) {
                        return -1;
                    } else {
                        i = index - 1;
                    }
                } else {
                    parentNode.childNodes.push(childNode);
                    lastLevel = level;
                }
            } else if (level <= maxLevel && parentNode.level > maxLevel) {
                parentNode.childNodes.push(childNode);
                lastLevel = level;
            } else {
                return i;
            }
        }
    }

    function createAElement(tag, index) {
        var a = document.createElement("a");
        a.style.cssText = "";
        a.setAttribute("href", "#" + tag.textContent);
        a.innerHTML = index.toString() + tag.textContent;
        return a;
    }

    function createOlElement() {
        var ol_el = document.createElement("ol");
        ol_el.style["line-height"] = "180%";
        ol_el.style["list-style-type"] = "none";
        ol_el.style["margin-left"] = "0";
        return ol_el
    }

    function createEmptyLiElement() {
        var emptyLiEle = document.createElement("li");
        return emptyLiEle
    }

    function getIndex(parentDirectory, directoryLevel, index) {
        if (directoryLevel === 0) {
            return parentDirectory + (index + 1).toString() + "."
        } else {
            return parentDirectory + (index + 1).toString() + ".";
        }
    }

    function createLeafElement(node, curDirectory) {
        var liEle = createEmptyLiElement();
        var aEle = createAElement(node.tag, curDirectory);
        liEle.appendChild(aEle);
        return liEle
    }

    function getArrowDownStyle() {
        return " width: 0;" +
            "    height: 0;" +
            "    position: relative;" +
            "    margin-right: 8px;" +
            "    top: 3px;" +
            "    display: inline-block;" +
            "    border: 6px outset;" +
            "    border-color: black transparent transparent transparent;"
    }

    function getArrowRightStyle() {
        return " width: 0;" +
            "    height: 0;" +
            "    left: 5px;" +
            "    position: relative;" +
            "    margin-right: 8px;" +
            "    display: inline-block;" +
            "    border: 6px solid;" +
            "    border-color: transparent transparent transparent black;"
    }
    /*
    <ol>
        <li><a>根节点1</a></li>
        <li><a>根节点2</a></li>
        <li>
            <div>
                <a><span>[-]</span>根节点3</a>
                <ol>
                    <li><a>子节点1</a></li>
                    <li><a>子节点2</a></li>
                    <li><a>子节点3</a></li>
                </ol>
            </div>
        </li>
        <li><a>根节点4</a></li>
     </ol>
    * */
    // node, 1.2.3 4 0
    function renderTree(node, parentDirectory, directoryLevel, index) {
        var childNodes = node.childNodes;
        var tagContent = node.tag.textContent;

        node.tag.setAttribute("id", tagContent);

        var curDirectory = getIndex(parentDirectory, directoryLevel, index);
        var directoryName = curDirectory + "&nbsp;" + tagContent;

        // 叶子节点
        if (childNodes.length === 0) {
            return "<li style='padding-left: 24px;'><a href='#" + tagContent + "'>" + directoryName + "</a></li>"
    //                return createLeafElement(node, curDirectory)
        }
        // 非叶子节点
        var childContent = "";
        for (var j = 0; j < node.childNodes.length; j++) {
            childContent += renderTree(node.childNodes[j], curDirectory, directoryLevel + 1, j);
        }

        return "<li>" +
            "   <div>" +
            "      <div>" +
            "         <div id='" + directoryName + "' class='open' style='" + getArrowDownStyle() + "' onclick='return switchDirectory(this);'></div>" +
            "         <a href='#" + tagContent + "' ondblclick='return switchByDbClick(this);'>" + directoryName + "</a>" +
            "      </div>" +
            "      <ol id='ol-" + directoryName + "' style='line-height: 180%;list-style-type: none; padding-left: 20px;'>" + childContent + "</ol>" +
            "   </div>" +
            "</li>";

        /*var liEle = createEmptyLiElement();
        var aEle = createAElement(node.tag, curDirectory);

        var parentElement = document.createElement("div");
        parentElement.appendChild(aEle);

        var olElement = createOlElement();

        var tempNode;
        for (var j = 0; j < node.childNodes.length; j++) {
            tempNode = node.childNodes[j];
            var element = renderTree(tempNode, curDirectory, directoryLevel + 1, j);
            olElement.appendChild(element);
        }
        parentElement.appendChild(olElement);

        liEle.appendChild(parentElement);
        return liEle;*/
    }

    function switchByDbClick(aEle) {
        switchDirectory(aEle.parentElement().firstChild)
    }

    // 开关目录
    function switchDirectory(ele) {
        var divEle = ele.parentNode.parentNode;
        var olEle = divEle.lastElementChild;
        if (ele.className === "open") {
            // 关闭
            olEle.style.cssText = "display:none;line-height: 180%;list-style-type: none; padding-left: 20px";
            ele.setAttribute("class", "close");
            ele.style.cssText = getArrowRightStyle();
        } else if (ele.className === "close") {
            // 打开
            olEle.style.cssText = "line-height: 180%;list-style-type: none; padding-left: 20px";
            ele.setAttribute("class", "open");
            ele.style.cssText = getArrowDownStyle();
        }
    }

    function switchAllDirectory(e) {
        var rootOlElement = document.getElementById("outline_ol");
        var ols = rootOlElement.getElementsByTagName("ol");
        var isOpen = false;

        if (e.innerHTML === '[+]') {
            e.setAttribute('title', 'collapse');
            e.innerHTML = '[-]';
            isOpen = true;
        } else {
            e.setAttribute('title', 'expand');
            e.innerHTML = '[+]';
        }


        for (var i = 0; i < ols.length; i++) {
            var olEle = ols[i];
            if (isOpen) {
                olEle.style.display = "block";
                olEle.parentNode.firstElementChild.firstElementChild.style.cssText = getArrowDownStyle();
            } else {
                olEle.style.display = "none";
                olEle.parentNode.firstElementChild.firstElementChild.style.cssText = getArrowRightStyle();
            }
        }

        e.blur();
        return false;
    }

    document.addEventListener("DOMContentLoaded", function () {
        // 1, 将body内容提取到div标签中
        wrapOldContentByDiv();

        // 2, 创建左边目录列表Div
        var directoryDiv = document.createElement("div");
        directoryDiv.setAttribute("id", "outline-list");
        directoryDiv.style.cssText = "width:20%;height:100%; float:left;font-size:16px,z-index:1;position: fixed;overflow: hidden;";

        // 3, 目录展开折叠开关
        addDirectorySwitch(directoryDiv);

        // 4, 创建目录列表
        var directoryOl = document.createElement("ol");
        directoryOl.style.cssText = "padding-left:14px;line-height:180%;list-style-type:none;height: 85%;padding-bottom: 30px; overflow: auto;";
        directoryOl.setAttribute("id", "outline_ol");
        directoryDiv.appendChild(directoryOl);
        var div1 = document.createElement("div");
        div1.style.cssText = "clear:both";

        // 插入目录
        document.body.insertBefore(directoryDiv, document.body.childNodes[0]);

        // 5, 获取所有的H标签
        var hTags = document.querySelectorAll('h1,h2,h3,h4,h5,h6');
        if (hTags.length < 2)
            return;

        var rootNode = {'tag': directoryOl, 'childNodes': [], 'level': 0};
        var maxLevel = parseInt(hTags[0].tagName.substr(1), 10);
        // 6, 创建树形结构
        createTree(rootNode, hTags, 0, maxLevel);

        // 7, 绘制树结构
        var htmlContent = "";
        for (var j = 0; j < rootNode.childNodes.length; j++) {
    //                var element = renderTree(rootNode.childNodes[j], '', 1, j);
    //                directoryOl.appendChild(element);

            htmlContent += renderTree(rootNode.childNodes[j], '', 1, j);
        }
        directoryOl.innerHTML = htmlContent;
    });
</script>

</head>
<body>
<center><font size="6" face="楷体"><strong><strong>深圳市华瑞安科技有限公司</strong></strong></br><strong><strong>软件二部-编码规范</strong></strong></font><br><br><table class="table" width="50%" border="0" cellspacing="0" cellpadding="0"><br>  <tr><br>    <th>版本号</th><br>    <th>作者</th><br>    <th>更新日期</th><br>    <th>修订内容</th><br>  </tr><br>  <tr><br>    <td>v1.0</td><br>    <td>王磊</td><br>    <td>2019.12.31</td><br>    <td>Create</td><br>  </tr><br>  <tr><br>    <td>v1.1</td><br>    <td>王磊</td><br>    <td>2021.1.23</td><br>    <td>Update</td><br>  </tr><br></table><br></center>



<h3 id="-">一、编程规约</h3>
<h4 id="-">（一）命名约定</h4>
<p><strong>1. 对所有标识符都通用的规则</strong><br>1.1 标识符只能使用ASCII字母和数字，因此每个有效的标识符名称都能匹配正则表达式\w+。<br>1.2 编码格式，源文件编码格式为 UTF-8，<br>1.3 空白字符，除了行结束符序列，ASCII水平空格字符(0x20，即空格)是源文件中唯一允许出现的空白字符，这意味着：所有其它字符串中的空白字符都要进行转义。制表符不用于缩进（可以在IDE中Tab键设置为若干个空格）。</p>
<p><strong>2. 包名</strong><br>包名全部小写，连续的单词只是简单地连接起来，不使用下划线。采用反域名命名规则，全部使用小写字母。一级包名为com，二级包名为xx（可以是公司或则个人的随便），三级包名根据应用进行命名，四级包名为模块名或层级名。<br>例如：<font color="red">com.hra.settings.service</font></p>
<table>
<thead>
<tr>
<th>包名</th>
<th>此包中包含</th>
</tr>
</thead>
<tbody>
<tr>
<td>com.xx.应用名称缩写.activity</td>
<td>页面用到的Activity类 (activitie层级名用户界面层)</td>
</tr>
<tr>
<td>com.xx.应用名称缩写.base</td>
<td>基础共享的类</td>
</tr>
<tr>
<td>com.xx.应用名称缩写.adapter</td>
<td>页面用到的Adapter类 (适配器的类)</td>
</tr>
<tr>
<td>com.xx.应用名称缩写.util</td>
<td>此包中包含：公共工具方法类（util模块名）</td>
</tr>
<tr>
<td>com.xx.应用名称缩写.bean</td>
<td>下面可分：vo、po、dto 此包中包含：JavaBean类</td>
</tr>
<tr>
<td>com.xx.应用名称缩写.model</td>
<td>此包中包含：模型类</td>
</tr>
<tr>
<td>com.xx.应用名称缩写.db</td>
<td>数据库操作类</td>
</tr>
<tr>
<td>com.xx.应用名称缩写.view</td>
<td>(或者 com.xx.应用名称缩写.widget )    自定义的View类等</td>
</tr>
<tr>
<td>com.xx.应用名称缩写.service</td>
<td>Service服务</td>
</tr>
<tr>
<td>com.xx.应用名称缩写.receiver</td>
<td>BroadcastReceiver服务</td>
</tr>
</tbody>
</table>
<p>【强制】包名统一使用小写，点分隔符之间有且仅有一个自然语义的英语单词。包名统一使用 单数形式，但是类名如果有复数含义，类名可以使用复数形式。</p>
<p><strong>3. 类名</strong><br>类名都以UpperCamelCase(大驼峰)风格编写。类名通常是名词或名词短语，接口名称有时可能是形容词或形容词短语。现在还没有特定的规则或行之有效的约定来命名注解类型。<br>名词，采用大驼峰命名法，尽量避免缩写，除非该缩写是众所周知的， 比如HTML,URL，如果类名称中包含单词缩写，则单词缩写的每个字母均应大写。</p>
<table>
<thead>
<tr>
<th>类</th>
<th>描述</th>
<th>例如</th>
</tr>
</thead>
<tbody>
<tr>
<td>Activity 类</td>
<td>Activity为后缀标识</td>
<td>欢迎页面类WelcomeActivity</td>
</tr>
<tr>
<td>Adapter类</td>
<td>Adapter 为后缀标识</td>
<td>新闻详情适配器 NewDetailAdapter</td>
</tr>
<tr>
<td>解析类</td>
<td>Parser为后缀标识</td>
<td>首页解析类HomePosterParser</td>
</tr>
<tr>
<td>工具方法类</td>
<td>Util或Manager为后缀标识（与系统或第三方的Utils区分）或功能+Util</td>
<td>线程池管理类：ThreadPoolManager</td>
</tr>
</tbody>
</table>
<blockquote>
<p>【强制】杜绝完全不规范的缩写，避免望文不知义。<br>反例：Abstractclass&quot;缩写”命名成AbsClass； condition “缩写”命名成condi，此类随 意缩写严重降低了代码的可阅读性。</p>
<p>【强制】抽象类命名使用Abstract或Base开头；异常类命名使用Exception结尾；测试类 命名以它要测试的类的名称开始，以Test结尾。</p>
</blockquote>
<p><strong>4. 方法名</strong><br>方法名、参数名、成员变量、局部变量都统一使用 LowerCamelCase 风格编写。方法名通常是动词或动词短语。</p>
<table>
<thead>
<tr>
<th>方法</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>initXX()</td>
<td>初始化相关方法,使用init为前缀标识，如初始化布局initView()</td>
</tr>
<tr>
<td>isXX() checkXX()</td>
<td>方法返回值为boolean型的请使用is或check为前缀标识</td>
</tr>
<tr>
<td>getXX()</td>
<td>返回某个值的方法，使用get为前缀标识</td>
</tr>
<tr>
<td>handleXX()</td>
<td>对数据进行处理的方法，尽量使用handle为前缀标识</td>
</tr>
<tr>
<td>displayXX()/showXX()</td>
<td>弹出提示框和提示信息，使用display/show为前缀标识</td>
</tr>
<tr>
<td>saveXX()</td>
<td>与保存数据相关的，使用save为前缀标识</td>
</tr>
<tr>
<td>resetXX()</td>
<td>对数据重组的，使用reset前缀标识</td>
</tr>
<tr>
<td>clearXX()</td>
<td>清除数据相关的</td>
</tr>
<tr>
<td>removeXXX()</td>
<td>清除数据相关的</td>
</tr>
<tr>
<td>drawXXX()</td>
<td>绘制数据或效果相关的，使用draw前缀标识</td>
</tr>
</tbody>
</table>
<p>下划线可能出现在JUnit测试方法名称中用以分隔名称的逻辑组件。一个典型的模式是：test_，例如testPop_emptyStack。<br>并不存在唯一正确的方式来命名测试方法。</p>
<p><strong>5. 【强制】常量命名全部大写，单词间用下划线隔开，力求语义表达完整清楚，不要嫌名字长。</strong><br>正例：MAX_STOCK_COUNT<br>反例：MAX_COUNT</p>
<p><strong>6. 【强制】中括号是数组类型的一部分</strong><br>数组定义如下：String口 args;<br>反例：使用String args［］的方式来定义。</p>
<p><strong>7. 【推荐】为了达到代码自解释的目标，任何自定义编程元素在命名时，使用尽量完整的单词 组合来表达其意。</strong><br>正例：从远程仓库拉取代码的类命名为PullCodeFromRemoteRepositoryo<br>反例：变量int a;的随意命名方式。</p>
<p><strong>8. 【推荐】如果模块、接口、类、方法使用了设计模式，在命名时体现出具体模式。</strong><br>说明：将设计模式体现在名字中，有利于阅读者快速理解架构设计理念。<br>正例：public class OrderFactory;<br>public class LoginProxy; public class ResourceObserver;</p>
<p><strong>9. 【推荐】接口类中的方法和属性不要加任何修饰符号</strong><br>（public也不要加），保持代码的简洁 性，并加上有效的Javadoc注释。尽量不要在接口里定义变量，如果一定要定义变量，肯定是 与接口方法相关，并且是整个应用的基础常量。<br>正例：接口方法签名：void f(); 接口基础常量表示：String COMPANY = &quot;HRA&quot;;<br>反例：接口方法定义：public abstract void f();</p>
<p><strong>10. 接口和实现类的命名有两套规则：</strong><br>1）    【强制】对于Service和DAO类，基于SOA的理念，暴露出来的服务一定是接口，内部 的实现类用Impl的后缀与接口区别。<br>正例：CacheServiceImpl 实现 CacheService 接口。<br>2）    【推荐】如果是形容能力的接口名称，取对应的形容词做接口名（通常是-able的形式）。 正例：AbstractTranslator 实现 Translatable。</p>
<p><strong>11.【参考】枚举类名建议带上Enum后缀，枚举成员名称需要全大写，单词间用下划线隔开。</strong><br>说明：枚举其实就是特殊的常量类，且构造方法被默认强制是私有。<br>正例：枚举名字为 ProcessStatusEnum 的成员名称：SUCCESS / UNKOWN_REASON。</p>
<pre><code class="lang-JAVA">private enum ProcessStatusEnum { 
    SUCCESS, 
    UNKOWN_REASON
}
</code></pre>
<blockquote>
<p>注意Android并不推荐使用枚举类型.</p>
</blockquote>
<h4 id="-">（二）常量定义</h4>
<p><strong>1. 【强制】不允许任何魔法值（即未经定义的常量）直接出现在代码中。</strong><br>魔法数值使代码的可读性大大下降。而且，如果同样的数值多次出现时，到底这些数值是不是带有同样的含义呢，谁也说不清楚。另一方面，如果本来应该使用相同数值的地方，一旦用错了，也很难发现。因此，我们应极力避免使用魔法数值。</p>
<pre><code class="lang-JAVA">// 反例
int [] array = new int[20];
for (int i = 0; i &lt; 20; i++){
    System.out.print(array[i]);
}
// 正例
static final int LENGTH_OF_ARRAY= 20;
int [] array = new int[LENGTH_OF_ARRAY];
for (int i = 0; i &lt; LENGTH_OF_ARRAY; i++){
    System.out.print(array[i]);
}
</code></pre>
<p><strong>2. 【强制】long或者Long初始赋值时，使用大写的L,不能是小写的l,小写容易跟数字1混淆，造成误解。</strong><br>说明：Long a = 2l;写的是数字的21,还是Long型的2?</p>
<p><strong>3. 【推荐】不要使用一个常量类维护所有常量，按常量功能进行归类，分开维护。</strong><br>说明：大而全的常量类，非得使用查找功能才能定位到修改的常量，不利于理解和维护。 正例：缓存相关常量放在类CacheConsts下；系统配置相关常量放在类ConfigConsts下。</p>
<p><strong>4. 【推荐】如果变量值仅在一个范围内变化，且带有名称之外的延伸属性，定义为枚举类。</strong></p>
<pre><code class="lang-JAVA">    // 正例
    public enum DateEnum {
        MONDAY(1),
        TUESDAY(2),
        WEDNESDAY(3),
        THURSDAY(4),
        FRIDAY(5),
        SATURDAY(6),
        SUNDAY(7)
        ...
    }
</code></pre>
<h4 id="-">（三）代码格式</h4>
<p><strong>1. 【强制】大括号的使用约定。</strong><br>如果是大括号内为空，则简洁地写成{}即可，不需要换行；如果是非空代码块则：<br>1）    左大括号前不换行。<br>2）    左大括号后换行。<br>3）    右大括号前换行。<br>4）    右大括号后还有else等代码则不换行；表示终止的右大括号后必须换行。</p>
<p><strong>2. 【强制】左小括号和字符之间不出现空格；</strong><br>同样，右小括号和字符之间也不出现空格。<br>反例：if (空格a == b空格)</p>
<p><strong>3. 【强制】if/for/while/switch/do等保留字与括号之间都必须加空格。</strong></p>
<p><strong>4. 【强制】任何二目、三目运算符的左右两边都需要加一个空格。 </strong><br>说明：运算符包括赋值运算符=、逻辑运算符&amp;&amp;、加减乘除符号等。</p>
<p><strong>5. 【强制】采用4个空格缩进，禁止使用tab字符。</strong><br>说明：如果使用tab缩进，必须设置1个tab为4个空格。IDEA设置tab为4个空格时，请勿勾选 Use tab character；而在 eclipse中，必须勾选insert spaces for tabs<br>正例：（涉及1-5点）</p>
<pre><code class="lang-JAVA">    public static void main(String[] args) {
        //缩进4个空格
        String say = &quot;hello&quot;;
        //运算符的左右必须有一个空格
        int flag = 0;
        //关键词if与括号之间必须有一个空格，括号内的f与左括号，0与右括号不需要空格
        if (flag == 0) {
            System.out.println(say);
        }
        //左大括号前加空格且不换行；左大括号后换行
        if (flag == 1) {
            System.out.println(&quot;world&quot;);
        //右大括号前换行，右大括号后有else，不用换行
        } else {
            System.out.println(&quot;ok&quot;);
        }
        //在右大括号后直接结束，则必须换行
    }
</code></pre>
<p><strong>6. 【强制】注释的双斜线与注释内容之间有且仅有一个空格。</strong><br>正例：//注释内容，注意在//和注释内容之间有一个空格。</p>
<p><strong>7. 【强制】单行字符数限制不超过120个，超出需要换行，换行时遵循如下原则：</strong><br>1)第二行相对第一行缩进4个空格，从第三行开始，不再继续缩进，参考示例。<br>2)运算符与下文一起换行。<br>3)方法调用的点符号与下文一起换行。<br>4)方法调用时，多个参数，需要换行时，在逗号后进行。<br>5)在括号前不要换行，见反例。<br>正例：</p>
<blockquote>
<p>StringBuffer sb = new StringBuffer();<br>//超过120个字符的情况下，换行缩进4个空格，点号和方法名称一起换行 sb.append(&quot;zi&quot;).append(&quot;xin&quot;)...<br>.append(&quot;huang&quot;)...<br>.append(&quot;huang&quot;)... .append(&quot;huang&quot;);<br>反例：<br>StringBuffer sb = new StringBuffer。；<br>//超过120个字符的情况下，不要在括号前换行 sb.append(&quot;zi&quot;).append(&quot;xin&quot;)...append<br>(&quot;huang&quot;);<br>//参数很多的方法调用可能超过120个字符，不要在逗号前换行<br>method(args1, args2, args3, ... , argsX);</p>
</blockquote>
<p><strong>8. 【强制】方法参数在定义和传入时，多个参数逗号后边必须加空格。</strong><br>正例：下例中实参的&quot;a&quot;,后边必须要有一个空格。<br>method(&quot;a&quot;, &quot;b&quot;, &quot;c&quot;);</p>
<p><strong>9. 【强制】IDE的text file encoding设置为UTF-8; IDE中文件的换行符使用Unix格式, 不要使用Windows格式。</strong></p>
<p><strong>10. 【推荐】没有必要增加若干空格来使某一行的字符与上一行对应位置的字符对齐。 </strong><br>正例：</p>
<blockquote>
<p>int a = 3;<br>long b = 4L;<br>float c = 5F;<br>StringBuffer sb = new StringBuffer();<br>说明：增加sb这个变量，如果需要对齐，则给a、b、c都要增加几个空格，在变量比较多的 情况下，是一种累赘的事情。</p>
</blockquote>
<h4 id="-oop-">（四）OOP规约</h4>
<p><strong>1. 【强制】避免通过一个类的对象引用访问此类的静态变量或静态方法。</strong><br>无谓增加编译器解析成本，直接用类名来访问即可。</p>
<p><strong>2. 【强制】相同参数类型，相同业务含义，才可以使用Java的可变参数，避免使用Object。</strong><br>说明：可变参数必须放置在参数列表的最后。(提倡同学们尽量不用可变参数编程)<br>正例： public User getUsers(String type, Integer... ids) {...}</p>
<p><strong>3. 【强制】不能使用过时的类或方法。</strong><br>说明：java.net.URLDecoder中的方法decode(String encodeStr)这个方法已经过时，应该使用双参数decode(String source, String encode)。接口提供方既然明确是过时接口，那么有义务同时提供新的接口；作为调用方来说，有义务去考证过时方法的新实现是什么。</p>
<p><strong>4. 【强制】Object的equals方法容易抛空指针异常，应使用常量或确定有值的对象来调用equals。</strong><br>正例：&quot;test”.equals(object);<br>反例：object.equals( &quot;test&quot;);</p>
<h4 id="-">（五）集合处理</h4>
<p><strong>1. 【强制】使用集合转数组的方法，必须使用集合的toArray(T[] array)。</strong><br>说明：使用toArray带参方法，入参分配的数组空间不够大时，toArray方法内部将重新分配 内存空间，并返回新数组地址；如果数组元素大于实际所需，下标为[list.size()]的数组 元素将被置为null，其它数组元素保持原值，因此最好将方法入参数组大小定义与集合元素 个数一致。</p>
<blockquote>
<p>正例：<br>List<Stringlist = new ArrayList<String>(2);<br>list.add(&quot;guan&quot;);<br>list.add(&quot;bao&quot;);<br>String[] array = new String[list.size()];<br>array = list.toArray(array);<br>反例：直接使用toArray无参方法存在问题，此方法返回值只能是Object[]类，若强转其它类型数组将出ClassCastException错误。</p>
</blockquote>
<p><strong>2. 【强制】使用工具类Arrays.asList()把数组转换成集合时，不能使用其修改集合相关的方法，它的add/remove/clear方法会抛出UnsupportedOperationException异常</strong>。<br>说明asList的返回对象是一个Arrays内部类，并没有实现集合的修改方法o Arrays.asList 体现的是适配器模式，只是转换接口，后台的数据仍是数组。<br>String[] str = new String<a href="&quot;you&quot;," title="wu"></a>;<br>List list = Arrays.asList(str);<br>第一种情况：list・add(&quot;yangguanbao&quot;);运行时异常。<br>第二种情况：str[0] = &quot;gujin&quot;;那么list.get(O)也会随之修改。</p>
<p><strong>3. 【强制】泛型通配符＜? extends T＞来接收返回的数据，此写法的泛型集合不能使用add方 法，而＜? super T＞不能使用get方法，做为接口调用赋值时易出错。</strong><br>说明：扩展说一下PECS(Producer Extends Consumer Super)原则：<br>第一、频繁往外读取内 容的，适合用＜? extends T＞。<br>第二、经常往里插入的，适合用＜? super T＞。</p>
<p><strong>4. 【强制】不要在foreach循环里进行元素的remove/add操作。</strong><br>remove元素请使用Iterator方式，如果并发操作，需要对Iterator对象加锁。</p>
<pre><code class="lang-JAVA">    // 正例：
    Iterator＜String＞ iterator = list.iterator();
    while (iterator.hasNext()) {
    String item = iterator.next();
    if (删除元素的条件) {
            iterator.remove();
        }
    }
    // 反例：
    List＜String＞ list = new ArrayList＜String＞();
    list.add(&quot;1&quot;);
    list.add(&quot;2&quot;);
    for (String item : list) {
        if (&quot;T&#39;.equals(item)) { 
            list.remove(item);
        }
    }
</code></pre>
<h4 id="-">（六）并发处理</h4>
<h4 id="-">（七）控制语句</h4>
<p><strong>1.【强制】在一个switch块内，每个case要么通过break/return等来终止。</strong><br>要么注释说明程 序将继续执行到哪一个case为止；在一个switch块内，都必须包含一个default语句并且 放在最后，即使它什么代码也没有。</p>
<p><strong>2.【强制】在if/else/for/while/do语句中必须使用大括号。</strong><br>即使只有一行代码，避免采用 单行的编码方式：if (condition) statements;</p>
<p><strong>3.【推荐】表达异常的分支时，少用if-else方式，这种方式可以改写成：</strong><br>if (condition) {<br>return obj;<br>}<br>//接着写else的业务逻辑代码；<br>说明：如果非得使用if()..・else if()..・else.・・方式表达逻辑，【强制】避免后续代码维 护困难，请勿超过3层。<br>正例：超过3层的if-else的逻辑判断代码可以使用卫语句、策略模式、状态模式等来实现， 其中卫语句示例如下：</p>
<pre><code class="lang-JAVA">public void today() {
if (isBusy()) {
System.out.println(“change time.”)；
return;
}
if (isFree()) {
System.out.println(“go to travel.”)；
return;
System.out.println(“stay at home to learn Alibaba Java Coding Guidelines return;
}
</code></pre>
<p><strong>4.【推荐】除常用方法(如getXxx/isXxx)等外，不要在条件判断中执行其它复杂的语句</strong>，将复杂逻辑判断的结果赋值给一个有意义的布尔变量名，以提高可读性。<br>说明：很多if语句内的逻辑相当复杂，阅读者需要分析条件表达式的最终结果，才能明确什么 样的条件执行什么样的语句，那么，如果阅读者分析逻辑表达式错误呢？ 正例：<br>//伪代码如下<br>final boolean existed = (file.open(fileName, &quot;w&quot;)!= null) &amp;&amp; (...)||(...);<br>if (existed) {)<br>反例：<br>if ((file.open(fileName, &quot;w&quot;) != null) &amp;&amp; (...) || (...))    {<br>}</p>
<h4 id="-">（八）注释规约</h4>
<p><strong>1.【强制】类、类属性、类方法的注释必须使用Javadoc规范。</strong>使用/<strong>内容*/格式，不得使用 // xxx方式。<br>说明：在IDE编辑窗口中，Javadoc方式会提示相关注释，生成Javadoc可以正确输出相应注 释；在IDE中，工程调用方法时，不进入方法即可悬浮提示方法、参数、返回值的意义，提高 阅读效率。
</strong>2.【强制】所有的抽象方法（包括接口中的方法）必须要用Javadoc注释**、除了返回值、参数、 异常说明外，还必须指出该方法做什么事情，实现什么功能。<br>说明：对子类的实现要求，或者调用注意事项，请一并说明。</p>
<p><strong>3.【强制】所有的类都必须添加创建者和创建日期。</strong></p>
<p><strong>4.【强制】方法内部单行注释，在被注释语句上方另起一行</strong>，使用//注释。方法内部多行注释<br>使用/<em>    </em>/注释，注意与代码对齐。</p>
<h4 id="-">（九）其它</h4>
<p><strong>1.【强制】获取当前毫秒数 System.currentTimeMillis();</strong>而不是 new Date().getTime(); 说明：如果想获取更加精确的纳秒级时间值，使用System.nanoTime（）的方式。在JDK8中， 针对统计时间等场景，推荐使用Instant类。</p>
<p><strong>2.【推荐】及时清理不再使用的代码段或配置信息。</strong><br>说明：对于垃圾代码或过时配置，坚决清理干净，避免程序过度臃肿，代码冗余。<br>正例：对于暂时被注释掉，后续可能恢复使用的代码片断，在注释代码上方，统一规定使用三 个斜杠（///）来说明注释掉代码的理由。</p>
<h3 id="-">二、异常日志</h3>
<h4 id="-">（一）异常处理</h4>
<p><strong>1.【强制】Java类库中定义的一类RuntimeException可以通过预先检查进行规避;</strong> 而不应该 通过 catch 来处理，比如：IndexOutOfBoundsException， NullPointerException 等等。 说明：无法通过预检查的异常除外，如在解析一个外部传来的字符串形式数字时，通过catch NumberFormatException 来实现。<br>正例：if (obj != null) {...}<br>反例：try { obj.method() } catch (NullPointerException e) {...}</p>
<p><strong>2.【强制】异常不要用来做流程控制，条件控制，因为异常的处理效率比条件分支低。</strong></p>
<p><strong>3.【强制】对大段代码进行try-catch，这是不负责任的表现。</strong>catch时请分清稳定代码和非稳定代码，稳定代码指的是无论如何不会出错的代码。对于非稳定代码的catch尽可能进行区分 异常类型，再做对应的异常处理。</p>
<p><strong>4.【强制】捕获异常是为了处理它，不要捕获了却什么都不处理而抛弃之。</strong>如果不想处理它，请 将该异常抛给它的调用者。最外层的业务使用者，必须处理异常，将其转化为用户可以理解的 内容。</p>
<p><strong>5.【强制】有try块放到了事务代码中，catch异常后，如果需要回滚事务，一定要注意手动回滚事务。</strong></p>
<p><strong>6.【强制】finally块必须对资源对象、流对象进行关闭，有异常也要做try-catch。</strong><br>说明：如果JDK7及以上，可以使用try-with-resources方式。</p>
<p><strong>7.【强制】不能在finally块中使用return，finally块中的return返回后方法结束执行</strong>，不会再执行try块中的return语句。</p>
<p><strong>8.【强制】捕获异常与抛异常，必须是完全匹配，或者捕获异常是抛异常的父类。</strong> 说明：如果预期对方抛的是绣球，实际接到的是铅球，就会产生意外情况。</p>
<p><strong>9.【推荐】方法的返回值可以为null，不强制返回空集合，或者空对象等，必须添加注释充分 说明什么情况下会返回null值。调用方需要进行null判断防止NPE问题。</strong><br>说明：本手册明确防止NPE是调用者的责任。即使被调用方法返回空集合或者空对象，对调用 者来说，也并非高枕无忧，必须考虑到远程调用失败、序列化失败、运行时异常等场景返回 null的情况。</p>
<p><strong>10.【推荐】防止NPE，是程序员的基本修养，注意NPE产生的场景：</strong><br>1)返回类型为基本数据类型，return包装数据类型的对象时，自动拆箱有可能产生NPE。<br>反例：public int f()    ( return Integer 对象},如果为 null，自动解箱抛NPE。<br>2）    数据库的查询结果可能为null。<br>3）    集合里的元素即使isNotEmpty，取出的数据元素也可能为null。<br>4）    远程调用返回对象时，一律要求进行空指针判断，防止NPE。<br>5）    对于Session中获取的数据，建议NPE检查，避免空指针。<br>6）    级联调用obj.getA（）.getB（）.getC（）； 一连串调用，易产生NPE。<br>正例：使用JDK8的Optional类来防止NPE问题。</p>
<p><strong>11.【推荐】定义时区分unchecked / checked异常</strong>，避免直接抛出new RuntimeException（）， 更不允许抛出Exception或者Throwable，应使用有业务含义的自定义异常。推荐业界已定义 过的自定义异常，如：DAOException / ServiceException 等。</p>
<h4 id="-">（二）日志规约</h4>
<h3 id="-">三、代码管理</h3>
<h4 id="-">（一）代码提交</h4>
<p><strong>1. commit message格式</strong></p>
<pre><code>&lt;type&gt;(&lt;scope&gt;):&lt;subject&gt;
</code></pre><p><strong>type(必须)</strong><br>用于说明git commit的类别，只允许使用下面的标识。<br>feat：新功能（feature）。<br>fix/to：修复bug，可以是QA发现的BUG，也可以是研发自己发现的BUG。<br>fix：产生diff并自动修复此问题。适合于一次提交直接修复问题<br>to：只产生diff不自动修复此问题。适合于多次提交。最终修复问题提交时使用fix<br>docs：文档（documentation）。<br>style：格式（不影响代码运行的变动）。<br>refactor：重构（即不是新增功能，也不是修改bug的代码变动）。<br>perf：优化相关，比如提升性能、体验。<br>test：增加测试。<br>chore：构建过程或辅助工具的变动。<br>revert：回滚到上一个版本。<br>merge：代码合并。<br>sync：同步主线或分支的Bug。<br><strong>scope(可选)</strong><br>scope用于说明 commit 影响的范围，比如数据层、控制层、视图层等等，视项目不同而不同。<br>例如在Angular，可以是location，browser，compile，compile，rootScope， ngHref，ngClick，ngView等。如果你的修改影响了不止一个scope，你可以使用<em>代替。<br><em>*subject(必须)</em></em><br>subject是commit目的的简短描述，不超过50个字符。<br>建议使用中文（感觉中国人用中文描述问题能更清楚一些）。<br>结尾不加句号或其他标点符号。<br>根据以上规范git commit message将是如下的格式：</p>
<blockquote>
<p>fix(DAO) : 用户查询缺少username属性<br>feat(Controller) : 用户查询接口开发</p>
</blockquote>

</body>
</html>
<!-- This document was created with MarkdownPad, the Markdown editor for Windows (http://markdownpad.com) -->
